package icu.d4peng.basic.knife4j.extension;

import com.github.xiaoymin.knife4j.core.extend.OpenApiExtendMarkdownChildren;
import com.github.xiaoymin.knife4j.core.extend.OpenApiExtendMarkdownFile;
import com.github.xiaoymin.knife4j.core.model.MarkdownProperty;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.github.xiaoymin.knife4j.core.util.CommonUtils;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import icu.d4peng.basic.knife4j.properties.Knife4jProperties;
import icu.d4peng.basic.knife4j.util.MarkdownUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author d4peng d4peng@qq.com
 * @date 2023-11-25 19:42:44
 */
public class OpenApiExtensionResolver {

	private static final Logger LOGGER = LoggerFactory.getLogger(OpenApiExtensionResolver.class);

	private final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();

	private final Map<String, List<OpenApiExtendMarkdownFile>> markdownFileMaps = new HashMap<>();

	/**
	 * 个性化配置
	 */
	private final Knife4jProperties.Knife4jSetting setting;

	/**
	 * 分组文档集合
	 */
	private final List<MarkdownProperty> markdownProperties;

	public OpenApiExtensionResolver(Knife4jProperties.Knife4jSetting setting,
			List<MarkdownProperty> markdownProperties) {
		this.setting = setting;
		this.markdownProperties = markdownProperties;
	}

	public List<OpenApiExtendMarkdownFile> getMarkdownFiles() {
		if (CollectionUtils.isNotEmpty(markdownFileMaps)) {
			List<OpenApiExtendMarkdownFile> markdownFiles = new LinkedList<>();
			for (Map.Entry<String, List<OpenApiExtendMarkdownFile>> entry : this.markdownFileMaps.entrySet()) {
				if (CollectionUtils.isNotEmpty(entry.getValue())) {
					markdownFiles.addAll(entry.getValue());
				}
			}
			return markdownFiles;

		}
		return Collections.emptyList();
	}

	public void start() {
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("Resolver method start...");
		}
		// 初始化其他文档
		// 其他文档是否为空
		if (CollectionUtils.isNotEmpty(this.markdownProperties)) {
			for (MarkdownProperty markdownProperty : this.markdownProperties) {
				if (StrUtil.isNotBlank(markdownProperty.getName())
						&& StrUtil.isNotBlank(markdownProperty.getLocations())) {
					String swaggerGroupName = StrUtil.isNotBlank(markdownProperty.getGroup())
							? markdownProperty.getGroup() : "default";
					OpenApiExtendMarkdownFile openApiExtendMarkdownFile = new OpenApiExtendMarkdownFile();
					openApiExtendMarkdownFile.setName(markdownProperty.getName());
					openApiExtendMarkdownFile.setGroup(swaggerGroupName);
					List<OpenApiExtendMarkdownChildren> allChildrenLists = new ArrayList<>();
					// 多个location以分号(;)进行分隔
					String[] locations = markdownProperty.getLocations().split(";");
					if (!CollectionUtils.isEmpty((Object) locations)) {
						for (String location : locations) {
							if (StrUtil.isNotBlank(location)) {
								List<OpenApiExtendMarkdownChildren> childrenList = readLocations(location);
								if (CollectionUtils.isNotEmpty(childrenList)) {
									allChildrenLists.addAll(childrenList);
								}

							}
						}
					}
					if (CollectionUtils.isNotEmpty(allChildrenLists)) {
						openApiExtendMarkdownFile.setChildren(allChildrenLists);
					}
					// 判断是否存在
					if (markdownFileMaps.containsKey(swaggerGroupName)) {
						markdownFileMaps.get(swaggerGroupName).add(openApiExtendMarkdownFile);
					}
					else {
						markdownFileMaps.put(swaggerGroupName, CollectionUtils.newArrayList(openApiExtendMarkdownFile));
					}
				}
			}
		}
		// 判断主页文档
		if (this.setting != null) {
			if (this.setting.isEnableHomeCustom()) {
				if (StrUtil.isNotBlank(this.setting.getHomeCustomPath())) {
					String content = readCustomHome(this.setting.getHomeCustomPath());
					// 赋值
					this.setting.setHomeCustomLocation(content);
				}
			}
		}
	}

	/**
	 * 读取自定义主页markdown的内容
	 *
	 */
	private String readCustomHome(String customHomeLocation) {
		String customHomeContent = "";
		try {
			Resource[] resources = resourceResolver.getResources(customHomeLocation);
			if (resources.length > 0) {
				// 取第1个
				Resource resource = resources[0];
				customHomeContent = new String(CommonUtils.readBytes(resource.getInputStream()),
						StandardCharsets.UTF_8);
			}
		}
		catch (Exception e) {
			LOGGER.warn("(Ignores) Failed to read CustomeHomeLocation Markdown files,Error Message:{} ",
					e.getMessage());
		}
		return customHomeContent;
	}

	/**
	 * 根据路径读取markdown文件
	 *
	 */
	private List<OpenApiExtendMarkdownChildren> readLocations(String locations) {
		try {
			List<OpenApiExtendMarkdownChildren> openApiExtendMarkdownChildrenList = new ArrayList<>();
			Resource[] resources = resourceResolver.getResources(locations);
			if (resources.length > 0) {
				for (Resource resource : resources) {
					OpenApiExtendMarkdownChildren markdownFile = readMarkdownChildren(resource);
					if (markdownFile != null) {
						openApiExtendMarkdownChildrenList.add(markdownFile);
					}
				}
				return openApiExtendMarkdownChildrenList;
			}
		}
		catch (Exception e) {
			LOGGER.warn("(Ignores) Failed to read Markdown files,Error Message:{} ", e.getMessage());
		}
		return null;
	}

	private OpenApiExtendMarkdownChildren readMarkdownChildren(Resource resource) {
		return MarkdownUtils.resolveMarkdownResource(resource);
	}

}
